package com.ec.au.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ec.au.constant.SysConstant;
import com.ec.au.domain.dto.UserLoginDTO;
import com.ec.au.domain.dto.UserRegisterFormDTO;
import com.ec.au.domain.dto.UserUpdateDTO;
import com.ec.au.domain.po.User;
import com.ec.au.domain.vo.LoginUser;
import com.ec.au.domain.vo.TokenVO;
import com.ec.au.mapper.UserMapper;
import com.ec.au.service.UserService;
import com.ec.au.utils.JwtUtil;
import com.ec.au.utils.RedisCache;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    @Autowired
    private AuthenticationManager authenticationManager;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private UserMapper userMapper;

    private BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();

    @Override
    public TokenVO login(UserLoginDTO userLoginDTO) {
        //AuthenticationManager authenticate进行用户认证
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userLoginDTO.getUsername(),userLoginDTO.getPassword());
        Authentication authenticate = authenticationManager.authenticate(authenticationToken);
        if(Objects.isNull(authenticate)){
            throw new RuntimeException("用户名或密码错误");
        }
        //使用userid生成token
        LoginUser loginUser = (LoginUser) authenticate.getPrincipal();
        long roleId=loginUser.getUser().getRoleId();
        if(userLoginDTO.getRolekey().equals("admin")&&roleId!=1){
            throw new RuntimeException("权限不足");
        }
        String userId = loginUser.getUser().getId().toString();
        String jwt = JwtUtil.createToken(userId);
        //authenticate存入redis
        redisCache.setCacheObject("login:"+userId,loginUser);
        //把token响应给前端
        TokenVO tokenVO =new TokenVO(jwt,loginUser.getUser());
        return tokenVO;
    }

    @Override
    public boolean logout() {
        //获取用户id
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        Long userid = loginUser.getUser().getId();
        //删除redis中用户的值
        redisCache.deleteObject("login:"+userid);
        return true;
    }

    @Override
    public boolean register(UserRegisterFormDTO userRegister) {
       // 根据用户名查询
       User user1 = getByUserName(userRegister.getUsername());
       if (!Objects.isNull(user1)) {
           throw new RuntimeException("该用户已存在");
       }
       if(StringUtils.isEmpty(userRegister.getPassword())){
           userRegister.setPassword(passwordEncoder.encode(SysConstant.DEFAULT_PASSWORD));
       }
       User user = User.builder()
               .userName(userRegister.getUsername())
               .password(passwordEncoder.encode(userRegister.getPassword()))
               .email(userRegister.getEmail())
               .phone(userRegister.getPhone())
               .roleId(userRegister.getRoleId())
               .status("0")
               .createTime(LocalDateTime.now())
               .updateTime(LocalDateTime.now())
               .build();
       // 保存用户
       save(user);
       return true;
   }

    @Transactional
    @Override
    public boolean updatePassword( UserUpdateDTO updateDTO) {
        // 根据用户名查询
        User user = getByUserName(updateDTO.getUsername());
        if (Objects.isNull(user)) {
            throw new RuntimeException("该用户不存在");
        }

        // 构建更新条件
        LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(User::getId, user.getId());

        // 设置需要更新的非空字段
        if (StringUtils.hasText(updateDTO.getPassword())) {
            if (!updateDTO.getPassword().equals(updateDTO.getRepassword())) {
                throw new RuntimeException("两次密码不一致");
            }
            updateWrapper.set(User::getPassword, passwordEncoder.encode(updateDTO.getPassword()));
        }

//        if(StringUtils.hasText(updateDTO.getPhone())) {
//            updateWrapper.set(User::getPhone, updateDTO.getPhone());
//        }
//        if (StringUtils.hasText(updateDTO.getEmail())) {
//            updateWrapper.set(User::getEmail, updateDTO.getEmail());
//        }

        updateWrapper.set(User::getUpdateTime, LocalDateTime.now());

        //  执行更新
        update(updateWrapper);

        return true;
    }

    @Override
    public boolean update(long userid,UserUpdateDTO updateDTO) {
        // 根据用户id查询
        User user = userMapper.selectById(userid);
        if (Objects.isNull(user)) {
            throw new RuntimeException("该用户不存在");
        }

        // 构建更新条件
        LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(User::getId, user.getId());

        // 设置需要更新的非空字段
//        if (StringUtils.hasText(updateDTO.getPassword())) {
//            if (!updateDTO.getPassword().equals(updateDTO.getRepassword())) {
//                throw new RuntimeException("两次密码不一致");
//            }
//            updateWrapper.set(User::getPassword, passwordEncoder.encode(updateDTO.getPassword()));
//        }

        if(StringUtils.hasText(updateDTO.getPhone())) {
            updateWrapper.set(User::getPhone, updateDTO.getPhone());
        }
        if (StringUtils.hasText(updateDTO.getEmail())) {
            updateWrapper.set(User::getEmail, updateDTO.getEmail());
        }

        updateWrapper.set(User::getUpdateTime, LocalDateTime.now());

        //  执行更新
        update(updateWrapper);

        return true;
    }

    @Override
    public User getByUserName(String userName) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUserName, userName);
        return userMapper.selectOne(queryWrapper);
    }

    @Override
    // 逻辑删除用户
    public boolean deleteUsersLogic(long[] ids) {
        List<Long> idList = Arrays.stream(ids).boxed().collect(Collectors.toList());
        // 更新 deleted 字段为 1 表示已删除
        UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
        updateWrapper.in("id", idList)
                .set("is_deleted", 1); // 只更新 is_deleted 字段

        return update(null, updateWrapper);
    }
}
